package com.rongji.cms.tools.websocket.runner;

import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIONamespace;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.protocol.Packet;
import com.corundumstudio.socketio.store.pubsub.DispatchMessage;
import com.corundumstudio.socketio.store.pubsub.PubSubStore;
import com.corundumstudio.socketio.store.pubsub.PubSubType;
import com.rongji.cms.tools.common.utils.StringUtils;
import com.rongji.cms.tools.websocket.constants.WsConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * @author yang
 * @date 2023/2/6 14:47
 * @description
 */
@Slf4j
@Component
public class WsRunner implements CommandLineRunner {

    @Autowired
    private SocketIOServer socketIoServer;

    @Resource
    private PubSubStore pubSubStore;

    @Resource
    private RedissonClient redisson;

    @Override
    public void run(String... args) throws Exception {
        socketIoServer.start();
        log.info("socket.io启动成功！");

        //订阅消息
        pubSubStore.subscribe(PubSubType.DISPATCH, data -> {
            Collection<SocketIOClient> clients = null;
            String room = data.getRoom();
            String namespace = data.getNamespace();
            Packet packet = data.getPacket();
            String jsonData = packet.getData();
            if(!StringUtils.isBlank(namespace)){
                SocketIONamespace socketIONamespace = socketIoServer.getNamespace(namespace);
                if(StringUtils.isBlank(room)){
                    clients = socketIONamespace.getRoomOperations(room).getClients();
                }
            }else{
                clients = socketIoServer.getBroadcastOperations().getClients();
            }
            if(!CollectionUtils.isEmpty(clients)){
                for (SocketIOClient client : clients) {
                    client.sendEvent(WsConstant.PUSH_MSG,jsonData);
                }
            }
        }, DispatchMessage.class);
//        addNameSpace(socketIoServer);


    }

    private void addNameSpace(SocketIOServer socketIoServer){
        SocketIONamespace testSpace = socketIoServer.addNamespace(WsConstant.TEST_NAME_SPACE);
        testSpace.addConnectListener(client -> {
            Map<String,Object> clientMap = new HashMap<>(16);
            String nameSpace = client.getNamespace().getName();
            String room = client.getHandshakeData().getSingleUrlParam("room");
            String sessionId = client.getSessionId().toString();
            log.info("testSpace连接成功, room={},nameSpace={}, sessionId={}", room, nameSpace,sessionId);
            if(StringUtils.isNotBlank(room)){
                client.joinRoom(room);
                clientMap.put("rooms",room);
            }
            clientMap.put("createTime", LocalDateTime.now().toString());
            redisson.getBucket(WsConstant.KEY_ROOM_PREFIX+WsConstant.TEST_NAME_SPACE+sessionId).trySet(clientMap);
        });
        testSpace.addDisconnectListener(client -> {
            log.info("testSpace,客户端:" + client.getSessionId() + "断开连接");
            String sessionId = client.getSessionId().toString();
            redisson.getBucket(WsConstant.KEY_ROOM_PREFIX+WsConstant.TEST_NAME_SPACE+sessionId).delete();
        });
        testSpace.addEventListener(WsConstant.TEST_EVINT,String.class,(client, data, ackSender) -> {
            client.sendEvent(WsConstant.TEST_EVINT,data);
            if (ackSender.isAckRequested()) {
                log.info("test接受到的消息. message={}", data);
            }
        });
    }
    
}
